package hc.j2me.ui;

import hc.core.ContextManager;
import hc.core.HCTimer;
import hc.core.IConstant;
import hc.core.IScreen;
import hc.core.util.NullStack;
import hc.core.util.Stack;
import hc.j2me.ScreenClientManager;
import hc.j2me.load.Mlet;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;

public class UIManager {
	private static Stack dispStack = new NullStack();
	private static MIDlet MAIN_MIDLET;
	public static Display UI_DISPLAY;
	private static Displayable CURR_DISP;
	
	public static MIDlet getMainMIDlet(){
		return MAIN_MIDLET;
	}
	
	public static Displayable getCurrDisplayable(){
		return CURR_DISP;
	}
	
	public static IScreen getDisplayableByName(String screenID){
		byte[] bs;
		try {
			bs = screenID.getBytes(IConstant.UTF_8);
		} catch (UnsupportedEncodingException e) {
			bs = screenID.getBytes();
		}
		return getDisplayableByName(bs, 0, bs.length);
	}
	
	public static IScreen getDisplayableByName(final byte[] bs, final int offset, final int len){
		Enumeration e = dispStack.elements();
		while(e.hasMoreElements()){
			Object obj = e.nextElement();
			if(obj instanceof IScreen){
				final IScreen screen = (IScreen)obj;
				if(screen.isSameScreenID(bs, offset, len)){
					return screen;
				}
			}
		}
		return null;
	}
	
	public static void setMainMIDlet(MIDlet mm){
		MAIN_MIDLET = mm;
		UI_DISPLAY = Display.getDisplay(MAIN_MIDLET);
	}
	
	public static boolean vibrate(int duration){
		return UI_DISPLAY.vibrate(duration);
	}
		
	private static CommandListener alertCommandListener = new CommandListener() {
		public void commandAction(Command arg0, Displayable arg1) {
			synchronized (LOCK) {
				UI_DISPLAY.setCurrent(CURR_DISP);
				delayAlertTimer.setEnable(true);
			}
		}
	};

	private static HCTimer delayAlertTimer = new HCTimer("", HCTimer.HC_INTERNAL_MS, false) {
		public void doBiz() {
			synchronized (LOCK) {
				if(alertVector.size() > 0){
					Alert back = (Alert)alertVector.elementAt(0);
					alertVector.removeElementAt(0);
	
					UI_DISPLAY.setCurrent(back, CURR_DISP);
				}else{
					isShowAlert = false;
				}
			}
			setEnable(false);
		}
	};
	private static Vector alertVector = new Vector();
	private static boolean isShowAlert = false;
	
	public static void dispAlert(Alert disp){
		disp.setCommandListener(alertCommandListener);

		synchronized (LOCK) {
			if(isShowAlert){
				alertVector.addElement(disp);
			}else{
				isShowAlert = true;
				UI_DISPLAY.setCurrent(disp, CURR_DISP);
			}
		}
	}
	
	public static void emptyStack(){
		dispStack.removeAllElements();
		CURR_DISP = null;
	}
	
	/**
	 * emptyStack为true，表示清空历史stack中的全部UI，即以本Displayable作为新起点
	 */
	public synchronized static void pushInAndSwithToNew(Displayable disp){
		if(disp instanceof PNGGameCanvas){
			ScreenClientManager.setScreenClient(disp);
		}
		
		if(CURR_DISP != null){
			dispStack.push(CURR_DISP);
		}
		
		CURR_DISP = disp;
		
		UI_DISPLAY.setCurrent(disp);
		
		System.gc();
	}
	
	public synchronized static void exitOrReturn(){
		if(CURR_DISP instanceof Mlet){
			((Mlet)CURR_DISP).exit();
		}
		
		Object obj = null;
		try{
			obj = dispStack.pop();
		}catch (Exception e) {
		}

		//增加断线后，自动退出系统
		if(obj == null || ContextManager.cmStatus == ContextManager.STATUS_EXIT){
//			hc.core.L.V=hc.core.L.O?false:LogManager.log("Client req shutdown");
			ContextManager.notifyShutdown();
		}else{
			if(obj instanceof PNGGameCanvas){
				ScreenClientManager.setScreenClient(obj);
				//hc.core.L.V=hc.core.L.O?false:LogManager.log("setScreen Back to PNGGameCanvas");
			}
			
			CURR_DISP = (Displayable)obj;
			UI_DISPLAY.setCurrent(CURR_DISP);
			System.gc();
		}
	}

	public static Boolean LOCK = new Boolean(false);
}
